﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jbe.TestSuite.Infrastructure.Interface;
using System.Windows.Media;
using System.ComponentModel;
using System.Collections.ObjectModel;
using Microsoft.Practices.Composite.Presentation.Commands;
using System.Windows.Media.Imaging;
using System.Reflection;
using Jbe.Composite.Extensions;
using System.Windows.Input;
using Jbe.TestSuite.Project.Properties;
using System.IO;
using System.Windows;

namespace Jbe.TestSuite.Project.Applications
{
    /// <summary>
    /// A simple data transfer object (DTO) that contains raw data about a person.
    /// </summary>
    public class ProjectItem
    {
        readonly List<ProjectItem> _children = new List<ProjectItem>();
        public IList<ProjectItem> Children
        {
            get { return _children; }
        }

        public string Name { get; set; }
        public string File { get; set; }
    }

    public class ProjectItemPresentationModel : INotifyPropertyChanged
    {
        #region Data

        readonly ReadOnlyCollection<ProjectItemPresentationModel> _children;
        readonly ProjectItemPresentationModel _parent;
        readonly ProjectItem _person;

        bool _isExpanded;
        bool _isSelected;

        #endregion // Data

        #region Constructors

        public ProjectItemPresentationModel(ProjectItem person)
            : this(person, null)
        {
        }

        private ProjectItemPresentationModel(ProjectItem person, ProjectItemPresentationModel parent)
        {
            _person = person;
            _parent = parent;

            _children = new ReadOnlyCollection<ProjectItemPresentationModel>(
                    (from child in _person.Children
                     select new ProjectItemPresentationModel(child, this))
                     .ToList<ProjectItemPresentationModel>());
        }

        #endregion // Constructors

        #region ProjectItem Properties

        public ReadOnlyCollection<ProjectItemPresentationModel> Children
        {
            get { return _children; }
        }

        public string Name
        {
            get { return _person.Name; }
        }

        public string File
        {
            get { return _person.File; }
        }

        #endregion // ProjectItem Properties

        #region Presentation Members

        #region IsExpanded

        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is expanded.
        /// </summary>
        public bool IsExpanded
        {
            get { return _isExpanded; }
            set
            {
                if (value != _isExpanded)
                {
                    _isExpanded = value;
                    this.OnPropertyChanged("IsExpanded");
                }

                // Expand all the way up to the root.
                if (_isExpanded && _parent != null)
                    _parent.IsExpanded = true;
            }
        }

        #endregion // IsExpanded

        #region IsSelected

        /// <summary>
        /// Gets/sets whether the TreeViewItem 
        /// associated with this object is selected.
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value != _isSelected)
                {
                    _isSelected = value;
                    if (value)
                    {
                        SelectedItem = this;
                    }
                    else
                    {
                        SelectedItem = null;
                    }

                    this.OnPropertyChanged("IsSelected");
                }
            }
        }

        #endregion // IsSelected

        #region NameContainsText

        public bool NameContainsText(string text)
        {
            if (String.IsNullOrEmpty(text) || String.IsNullOrEmpty(this.Name))
                return false;

            return this.Name.IndexOf(text, StringComparison.InvariantCultureIgnoreCase) > -1;
        }

        #endregion // NameContainsText

        #region Parent

        public ProjectItemPresentationModel Parent
        {
            get { return _parent; }
        }

        #endregion // Parent

        #endregion // Presentation Members        

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion // INotifyPropertyChanged Members



        private static ProjectItemPresentationModel _selectedItem = null;
        // This is public get-only here but you could implement a public setter which also selects the item.
        // Also this should be moved to an instance property on a VM for the whole tree, otherwise there will be conflicts for more than one tree.
        public static ProjectItemPresentationModel SelectedItem
        {
            get { return _selectedItem; }
            private set
            {
                if (_selectedItem != value)
                {
                    _selectedItem = value;
                }
            }
        }
    }
}
